package th.android.sudoku;

import java.util.Random;

public class NewSudokuGenerator {

    private final static int N = 9;

    private int[] mLineTags = new int[N];
    private int[] mColumnTags = new int[N];
    private int[] mBlockTags = new int[N];

    private int[][] mGeneratedSudoku = new int[N][N];

    public void generate() {
        int count = 0;
        Random random = new Random();
        Cell cell = new Cell(0, 0);
        while (count < 30) {
            int randomValue = random.nextInt(81);
            int cellValue = random.nextInt(9) + 1;
            cell.x = randomValue / 9;
            cell.y = randomValue % 9;
            while (mGeneratedSudoku[cell.x][cell.y] != 0 || !isValid(cell, cellValue)) {
                randomValue = (randomValue + 1) % 81;
                cell.x = randomValue / 9;
                cell.y = randomValue % 9;
            }
            count++;
            mGeneratedSudoku[cell.x][cell.y] = cellValue;
            mLineTags[cell.x] |= (1 << cellValue - 1);
            mColumnTags[cell.y] |= (1 << cellValue - 1);
            mBlockTags[cell.x / 3 * 3 + cell.y / 3] |= (1 << cellValue - 1);
        }
        ThSudokuGenerator.printArr(mGeneratedSudoku);
    }

    private boolean isValid(Cell axis, int cellValue) {
        final int i = axis.x, j = axis.y;
        final int lineTag = mLineTags[i];
        final int columnTag = mColumnTags[j];
        final int blockTag = mBlockTags[i / 3 * 3 + j / 3];
        int offset = cellValue - 1;
        return (lineTag >> offset & 1) == 0 && (columnTag >> offset & 1) == 0 && (blockTag >> offset & 1) == 0;
    }

    public static void main(String[] args) {
        NewSudokuGenerator generator = new NewSudokuGenerator();
        generator.generate();
    }

}
